package com.shanjupay.merchant.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shanjupay.common.domain.BusinessException;
import com.shanjupay.common.domain.CommonErrorCode;
import com.shanjupay.common.domain.PageVO;

import com.shanjupay.merchant.api.MerchantService;
import com.shanjupay.merchant.api.dto.*;
import com.shanjupay.merchant.convert.MerchantConvert;
import com.shanjupay.merchant.convert.StaffConvert;
import com.shanjupay.merchant.convert.StoreConvert;

import com.shanjupay.merchant.entity.Merchant;
import com.shanjupay.merchant.entity.Staff;
import com.shanjupay.merchant.entity.Store;
import com.shanjupay.merchant.entity.StoreStaff;
import com.shanjupay.merchant.mapper.MerchantMapper;
import com.shanjupay.merchant.mapper.StaffMapper;
import com.shanjupay.merchant.mapper.StoreMapper;
import com.shanjupay.merchant.mapper.StoreStaffMapper;
import com.shanjupay.user.api.AuthorizationService;
import com.shanjupay.user.api.TenantService;
import com.shanjupay.user.api.dto.authorization.RoleDTO;
import com.shanjupay.user.api.dto.tenant.CreateAccountRequestDTO;
import com.shanjupay.user.api.dto.tenant.CreateTenantRequestDTO;
import com.shanjupay.user.api.dto.tenant.TenantDTO;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.function.DoubleToIntFunction;

/**
 * @program: shanjupay
 * @description:
 * @author: Mr.Hkc
 * @create: 2020-08-18 11:30
 **/

@Service
@Transactional
public class MerchantServiceImpl implements MerchantService {


    @Autowired
    MerchantMapper merchantMapper;

    @Autowired
    StoreMapper storeMapper;

    @Autowired
    StaffMapper staffMapper;

    @Autowired
    StoreStaffMapper storeStaffMapper;

    @Reference
    TenantService tenantService;

    @Reference
    AuthorizationService authService;


    /**
     * 分页查询商户下的所有员工
     *
     * @param staffDTO
     * @param pageNo
     * @param pageSize
     * @return
     * @throws BusinessException
     */
    public PageVO<StaffDTO> queryStaffByPage(StaffDTO staffDTO, Integer pageNo, Integer pageSize) throws BusinessException {
        //创建分页
        Page<Staff> page = new Page<>(pageNo, pageSize);

        //构建查询条件
        LambdaQueryWrapper<Staff> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        if (staffDTO != null && staffDTO.getMerchantId() != null) {
            lambdaQueryWrapper.eq(Staff::getMerchantId, staffDTO.getMerchantId());
        }
        if (staffDTO != null && StringUtils.isNotBlank(staffDTO.getUsername())) {
            lambdaQueryWrapper.like(Staff::getUsername, staffDTO.getUsername());
        }
        if (staffDTO != null && StringUtils.isNotBlank(staffDTO.getFullName())) {
            lambdaQueryWrapper.like(Staff::getFullName, staffDTO.getFullName());
        }
        if (staffDTO != null && staffDTO.getStaffStatus() != null) {
            lambdaQueryWrapper.eq(Staff::getStaffStatus, staffDTO.getStaffStatus());
        }
        //执行查询
        IPage<Staff> staffIPage = staffMapper.selectPage(page, lambdaQueryWrapper);

        //转换 entityList转dtoList
        List<StaffDTO> staffDTOList = StaffConvert.INSTANCE.listentity2dto(staffIPage.getRecords());
        //封装结果集
        PageVO<StaffDTO> staffDTOS = new PageVO<>(staffDTOList, staffIPage.getTotal(), pageNo, pageSize);

        if (staffDTOS.getCounts() == 0) {
            return staffDTOS;
        }
        //添加员工所属门店信息
        for (StaffDTO staff : staffDTOS) {
            StoreDTO storeDTO = queryStoreById(staff.getStoreId());
            if (storeDTO != null) {
                staff.setStoreName(storeDTO.getStoreName());
            }
        }
        return staffDTOS;
    }

    /**
     * 删除员工
     * @param id
     * @throws BusinessException
     */
    @Transactional
    public void removeStaff(Long id) throws BusinessException {
        Staff staff = staffMapper.selectById(id);
        //清除员工和门店的关系
        storeStaffMapper.delete(new LambdaQueryWrapper<StoreStaff>().eq(StoreStaff::getStaffId, staff.getId()));
        //删除员工对应的账号,账号-角色之间的关系
        Long tenantId = queryMerchantById(staff.getMerchantId()).getTenantId();
        tenantService.unbindTenant(tenantId,staff.getUsername()); //将某账号从租户内移除,租户管理员不可移除
        //删除员工
        staffMapper.deleteById(staff);
    }

    /**
     * 修改员工信息
     * @param staffDTO
     * @param roleCodes
     * @throws BusinessException
     */
    public void modifyStaff(StaffDTO staffDTO, String[] roleCodes) throws BusinessException {
        Staff staff = staffMapper.selectById(staffDTO.getId());
        if (staff == null) {
            throw new BusinessException(CommonErrorCode.E_200013);
        }
        //更新员工的信息
        staff.setFullName(staffDTO.getFullName());
        staff.setPosition(staffDTO.getPosition());
        staff.setStoreId(staffDTO.getStoreId());
        staffMapper.updateById(staff);
        //处理员工的角色是否有修改
        Long tenantId = queryMerchantById(staff.getMerchantId()).getTenantId();
        tenantService.getAccountRoleBind(staff.getUsername(),tenantId,roleCodes);
    }

    /**
     * 查询员工详情
     * @param id
     * @param tenantId
     * @return
     */
    public StaffDTO queryStaffDetail(Long id, Long tenantId) {
        StaffDTO staffDTO = queryStaffById(id);
        //根据用户名和租户id查询角色信息
        List<RoleDTO> roles = authService.queryRoleByUsername(staffDTO.getUsername(),tenantId);
        List<StaffRoleDTO> staffRoles = new ArrayList<>();
        if (!roles.isEmpty()) {
            for (RoleDTO roleDTO : roles) {
                StaffRoleDTO staffRoleDTO = new StaffRoleDTO();
                BeanUtils.copyProperties(roleDTO,staffRoleDTO);
                staffRoles.add(staffRoleDTO);
            }
        }
        staffDTO.setRoles(staffRoles);
        return staffDTO;
    }

    /**
     * 获取员工详情
     * @param id
     * @return
     */
    public StaffDTO queryStaffById(Long id) {
        Staff staff = staffMapper.selectById(id);
        if (staff == null) {
            throw new BusinessException(CommonErrorCode.E_200013);
        }
        StaffDTO staffDTO = StaffConvert.INSTANCE.entity2dto(staff);
        //根据员工归属门店id，获取门店信息
        StoreDTO store = queryStoreById(staff.getStoreId());
        staffDTO.setStoreName(store.getStoreName());
        return staffDTO;
    }


    /**
     * 商户新增员工和账号
     *
     * @param staffDTO
     * @param roleCodes
     * @throws BusinessException
     */
    public void createStaffAndAccount(StaffDTO staffDTO, String[] roleCodes) throws BusinessException {
        //1.新增员工
        createStaff(staffDTO);
        //获取商户的租户id
        Long tenantId = queryMerchantById(staffDTO.getMerchantId()).getTenantId();
        CreateAccountRequestDTO accountRequest = new CreateAccountRequestDTO();
        accountRequest.setMobile(staffDTO.getMobile());
        accountRequest.setUsername(staffDTO.getUsername());
        accountRequest.setPassword(staffDTO.getPassword());

        //在租户内创建账号并绑定角色,包含校验账号是否存在以及角色是否绑定
        tenantService.checkCreateStaffAccountRole(accountRequest, tenantId, roleCodes);
    }

    /**
     * 删除某门店
     *
     * @param id
     * @throws BusinessException
     */
    @Transactional
    public void removeStore(Long id) throws BusinessException {
        Store store = storeMapper.selectById(id);
        //根门店不可删除
        if (store.getParentId() == null) {
            throw new BusinessException(CommonErrorCode.E_200018);
        }
        //清除门店和员工关系
        storeStaffMapper.delete(new LambdaQueryWrapper<StoreStaff>().eq(StoreStaff::getStoreId, id));
        //清除员工所属的门店
        staffMapper.update(null, new LambdaUpdateWrapper<Staff>().eq(Staff::getStoreId, id).set(Staff::getStoreId, null));
        //删除门店
        storeMapper.deleteById(id);
    }

    /**
     * 修改门店
     *
     * @param storeDTO
     * @param staffIds
     * @throws BusinessException
     */
    public void modifyStore(StoreDTO storeDTO, List<Long> staffIds) throws BusinessException {
        //更新门店的信息
        Store store = StoreConvert.INSTANCE.dto2entity(storeDTO);
        storeMapper.updateById(store);
        if (staffIds != null) {
            //清除门店绑定的管理员
            storeStaffMapper.delete(new LambdaQueryWrapper<StoreStaff>().eq(StoreStaff::getStoreId, store.getId()));
            //重新绑定关系,设置管理员
            for (Long staffId : staffIds) {
                bindStaffToStore(store.getId(), staffId);
            }
        }

    }

    /**
     * 获取门店详情
     *
     * @param id
     * @return
     */
    public StoreDTO queryStoreById(Long id) {
        Store store = storeMapper.selectById(id);
        StoreDTO storeDTO = StoreConvert.INSTANCE.entity2dto(store);
        if (storeDTO != null) {
            List<StaffDTO> staffs = queryStoreAdmin(id);
            storeDTO.setStaffs(staffs);
        }
        return storeDTO;
    }

    public List<StaffDTO> queryStoreAdmin(Long storeId) {
        //根据门店获取管理员的id
        List<StoreStaff> storeStaffs = storeStaffMapper.selectList(new LambdaQueryWrapper<StoreStaff>().eq(StoreStaff::getStoreId, storeId));
        List<Staff> staff = null;
        if (!storeStaffs.isEmpty()) {
            List<Long> staffIds = new ArrayList<>();
            //查询结果不为空,则遍历获取管理员id
            for (StoreStaff storeStaff : storeStaffs) {
                staffIds.add(storeStaff.getStaffId());
            }
            //根据id获取管理员信息
            staff = staffMapper.selectBatchIds(staffIds);
        }
        return StaffConvert.INSTANCE.listentity2dto(staff);
    }


    /**
     * 商户下新增门店,并设置管理员
     *
     * @param storeDTO
     * @param staffIds
     * @return
     * @throws BusinessException
     */
    public StoreDTO createStore(StoreDTO storeDTO, List<Long> staffIds) throws BusinessException {
        //设置根门店
        Long rootStoreId = getRootStore(storeDTO.getMerchantId());
        storeDTO.setParentId(rootStoreId);
        //新增门店
        Store store = StoreConvert.INSTANCE.dto2entity(storeDTO);
        storeMapper.insert(store);
        if (staffIds != null) {
            //设置管理员
            for (Long staffId : staffIds) {
                bindStaffToStore(store.getId(), staffId);
            }
        }
        return StoreConvert.INSTANCE.entity2dto(store);
    }

    /**
     * 商户资质审核
     *
     * @param merchantId
     * @param auditStatus
     * @throws BusinessException
     */
    public void verifyMerchant(Long merchantId, String auditStatus) throws BusinessException {
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new BusinessException(CommonErrorCode.E_200016);
        }
        merchant.setAuditStatus(auditStatus);
        merchantMapper.updateById(merchant);
    }

    /**
     * 商户分页查询
     *
     * @param merchantQueryDTO
     * @param pageNo
     * @param pageSize
     * @return
     * @throws BusinessException
     */
    public PageVO<MerchantDTO> queryMerchantPage(MerchantQueryDTO merchantQueryDTO, Integer pageNo, Integer pageSize) throws BusinessException {
        //分页 -> 默认首页和每页10条数据
        IPage<Merchant> page = new Page<>(pageNo == null ? 1 : pageNo, pageSize == null ? 10 : pageSize);
        LambdaQueryWrapper<Merchant> lambdaQueryWrapper = new LambdaQueryWrapper<Merchant>();
        //拼装查询条件
        if (merchantQueryDTO != null && StringUtils.isNotBlank(merchantQueryDTO.getMerchantName())) {
            lambdaQueryWrapper.like(Merchant::getMerchantName, merchantQueryDTO.getMerchantName());
        }
        if (merchantQueryDTO != null && StringUtils.isNotBlank(merchantQueryDTO.getMobile())) {
            lambdaQueryWrapper.eq(Merchant::getMobile, merchantQueryDTO.getMobile());
        }
        if (merchantQueryDTO != null && StringUtils.isNotBlank(merchantQueryDTO.getMerchantType())) {
            lambdaQueryWrapper.eq(Merchant::getTenantId, merchantQueryDTO.getMerchantType());
        }
        if (merchantQueryDTO != null && merchantQueryDTO.getAuditStatus() != null) {
            lambdaQueryWrapper.eq(Merchant::getAuditStatus, merchantQueryDTO.getAuditStatus());
        }
        IPage<Merchant> result = merchantMapper.selectPage(page, lambdaQueryWrapper);
        if (result.getTotal() > 0) {
            List<MerchantDTO> merList = MerchantConvert.INSTANCE.entityList2dtoList(result.getRecords());
            return new PageVO<MerchantDTO>(merList, result.getTotal(), pageNo, pageSize);
        }

        return new PageVO<MerchantDTO>(new ArrayList<MerchantDTO>(), 0, pageNo, pageSize);
    }

    /**
     * 查询门店是否属于商户
     *
     * @param storeId
     * @param merchantId
     * @return
     */
    public Boolean queryStoreInMerchant(Long storeId, Long merchantId) {
        Integer count = storeMapper.selectCount(new LambdaQueryWrapper<Store>()
                .eq(Store::getId, storeId)
                .eq(Store::getMerchantId, merchantId));
        return count > 0;
    }

    /**
     * @param storeDTO 查询条件:必要->商户id
     * @param pageNo   页码
     * @param size     记录数
     * @return
     * @throws BusinessException
     */
    public PageVO<StoreDTO> queryStoreByPage(StoreDTO storeDTO, Integer pageNo, Integer size) throws BusinessException {
        Page<Store> page = new Page<>(pageNo, size);
        //查询条件封装
        LambdaQueryWrapper<Store> queryWrapper = new LambdaQueryWrapper<>();
        //如果传入商户id,此时要拼装查询条件
        if (storeDTO != null && storeDTO.getMerchantId() != null) {
            queryWrapper.eq(Store::getMerchantId, storeDTO.getMerchantId());
        }
        //根据其他条件查询 门店名称
        if (storeDTO != null && StringUtils.isNotEmpty(storeDTO.getStoreName())) {
            queryWrapper.like(Store::getStoreName, storeDTO.getStoreName());
        }
        //分页查询数据库
        IPage<Store> storeIPage = storeMapper.selectPage(page, queryWrapper);
        //查询列表
        List<Store> records = storeIPage.getRecords();
        List<StoreDTO> storeDTOS = StoreConvert.INSTANCE.listentity2dto(records);
        return new PageVO<StoreDTO>(storeDTOS, storeIPage.getTotal(), pageNo, size);
    }

    /**
     * 根据租户id查询商户信息
     *
     * @param tenantId
     * @return
     */
    public MerchantDTO queryMerchantByTenantId(Long tenantId) {
        Merchant merchant = merchantMapper.selectOne(new LambdaQueryWrapper<Merchant>().eq(Merchant::getTenantId, tenantId));
        return MerchantConvert.INSTANCE.entity2dto(merchant);
    }

    /**
     * 员工与门店绑定
     *
     * @param storeId
     * @param staffId
     */
    public void bindStaffToStore(Long storeId, Long staffId) throws BusinessException {
        StoreStaff storeStaff = new StoreStaff();
        storeStaff.setStoreId(storeId);
        storeStaff.setStaffId(staffId);
        storeStaffMapper.insert(storeStaff);
    }

    /**
     * 新增门店
     *
     * @param storeDTO 门店信息
     * @return
     * @throws BusinessException
     */
    public StoreDTO createStore(StoreDTO storeDTO) throws BusinessException {
        Store entity = StoreConvert.INSTANCE.dto2entity(storeDTO);
        //新增门店
        storeMapper.insert(entity);
        return StoreConvert.INSTANCE.entity2dto(entity);
    }

    /**
     * 新增员工
     *
     * @param staffDTO
     * @return
     * @throws BusinessException
     */
    public StaffDTO createStaff(StaffDTO staffDTO) throws BusinessException {
        String mobile = staffDTO.getMobile();
        if (StringUtils.isBlank(mobile)) {
            throw new BusinessException(CommonErrorCode.E_100112);
        }
        if (isExistStaffByMobile(mobile, staffDTO.getMerchantId())) {
            throw new BusinessException(CommonErrorCode.E_100113);
        }
        String username = staffDTO.getUsername();
        if (StringUtils.isBlank(username)) {
            throw new BusinessException(CommonErrorCode.E_100110);
        }
        if (isExistStaffByUserName(username, staffDTO.getMerchantId())) {
            throw new BusinessException(CommonErrorCode.E_100114);
        }

        Staff entity = StaffConvert.INSTANCE.dto2entity(staffDTO);
        //新增员工
        staffMapper.insert(entity);
        return StaffConvert.INSTANCE.entity2dto(entity);
    }

    public MerchantDTO queryMerchantById(Long id) {
        Merchant merchant = merchantMapper.selectById(id);
       /* MerchantDTO merchantDTO = new MerchantDTO();
        merchantDTO.setId(merchant.getId());
        merchantDTO.setMerchantName(merchant.getMerchantName());*/
        //....
        return MerchantConvert.INSTANCE.entity2dto(merchant);
    }

    /**
     * 创建租户如果已存在租户则返回租户信息，否则新增租户、新增租户管理员，同时初始化权限
     * 1.若管理员用户名已存在，禁止创建
     * 2.手机号已存在，禁止创建
     * 3.创建根租户对应账号时，需要手机号，账号的用户名密码
     */
    public MerchantDTO createMerchant(MerchantDTO merchantDTO) {
      /*  // 1.校验
        if (merchantDTO == null) {
            throw new BusinessException(CommonErrorCode.E_100108);
        }
        //手机号非空校验
        if (StringUtils.isBlank(merchantDTO.getMobile())) {
            throw new BusinessException(CommonErrorCode.E_100112);
        }
        //校验手机号的合法性
        if (!PhoneUtil.isMatches(merchantDTO.getMobile())) {
            throw new BusinessException(CommonErrorCode.E_100109);
        }
        //联系人非空校验
        if (StringUtils.isBlank(merchantDTO.getUsername())) {
            throw new BusinessException(CommonErrorCode.E_100110);
        }
        //密码非空校验
        if (StringUtils.isBlank(merchantDTO.getPassword())) {
            throw new BusinessException(CommonErrorCode.E_100111);
        }*/
        //校验手机号的唯一性,根据商户的手机号查询商户表，如果存在记录则说明已有相同的手机号重复
        Integer count = merchantMapper.selectCount(new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getMobile, merchantDTO.getMobile()));
        if (count > 0) {
            throw new BusinessException(CommonErrorCode.E_100113);
        }
        //调用SaaS接口
        //构造调用的参数
        CreateTenantRequestDTO createTenantRequestDTO = new CreateTenantRequestDTO();
        createTenantRequestDTO.setMobile(merchantDTO.getMobile());
        createTenantRequestDTO.setUsername(merchantDTO.getUsername());
        createTenantRequestDTO.setPassword(merchantDTO.getPassword());

        createTenantRequestDTO.setTenantTypeCode("shanju-merchant"); //租户类型
        createTenantRequestDTO.setBundleCode("shanju-merchant"); //套餐,根据套餐进行分配权限
        createTenantRequestDTO.setName(merchantDTO.getUsername()); //租户名称和账号名一样


        //如果租户在SaaS已经存在,SaaS直接返回此租户的信息,否则进行添加
        TenantDTO tenantAndAccount = tenantService.createTenantAndAccount(createTenantRequestDTO);
        //获取租户的id
        if (tenantAndAccount == null || tenantAndAccount.getId() == null) {
            throw new BusinessException(CommonErrorCode.E_200012);
        }
        Long tenantId = tenantAndAccount.getId();

        //根据租户id从商户表查询,如果存在记录则不允许添加商户  租户id在商户表唯一
        int count1 = merchantMapper.selectCount(new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getTenantId, tenantId));
        if (count1 > 0) {
            throw new BusinessException(CommonErrorCode.E_200017);
        }
        //Merchant merchant = new Merchant();
        // merchant.setMobile(merchantDTO.getMobile());
        //使用MapStruct进行对象转换

        //设置所对应的租户的id
        merchantDTO.setTenantId(tenantId);
        //设置审核状态0->未申请 1->已申请待审核
        merchantDTO.setAuditStatus("0");
        Merchant entity = MerchantConvert.INSTANCE.dto2entity(merchantDTO);
        //保存商户

        merchantMapper.insert(entity);

        //新增门店
        StoreDTO storeDTO = new StoreDTO();
        storeDTO.setStoreName("根门店");
        storeDTO.setMerchantId(entity.getId());//商户id
        //storeDTO.setStoreStatus(true);
        StoreDTO store = createStore(storeDTO);
        //新增员工
        StaffDTO staffDTO = new StaffDTO();
        staffDTO.setMobile(merchantDTO.getMobile()); //手机号
        staffDTO.setUsername(merchantDTO.getUsername()); //账号
        staffDTO.setStoreId(store.getId()); //员工所属门店的id
        staffDTO.setMerchantId(entity.getId());
        staffDTO.setStaffStatus(true); //员工状态为启用
        StaffDTO staff = createStaff(staffDTO);

        //为门店设置管理员(权限)
        bindStaffToStore(store.getId(), staff.getId());

        //将新增商家id返回
        //merchantDTO.setId(merchant.getId());
        //将entity转成dto
        return MerchantConvert.INSTANCE.entity2dto(entity);
    }

    /**
     * 资质申请接口
     *
     * @param merchantId  商户id
     * @param merchantDTO 资质申请信息
     * @throws BusinessException
     */
    public void applyMerchant(Long merchantId, MerchantDTO merchantDTO) throws BusinessException {
        if (merchantId == null || merchantDTO == null) {
            throw new BusinessException(CommonErrorCode.E_300009);
        }
        //校验商户id合法性,查询表,如果没有记录则认为非法
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new BusinessException(CommonErrorCode.E_200002);
        }
        //将必要的参数重新设置进entity
        merchantDTO.setId(merchant.getId());
        merchantDTO.setMobile(merchant.getMobile());   //因为在资质申请的时候手机号不让改,所以还使用原来数据库的数据
        merchantDTO.setAuditStatus("1"); //审核状态为"1" 已审核状态
        merchantDTO.setTenantId(merchant.getTenantId());
        //将dto转成entity
        Merchant entity = MerchantConvert.INSTANCE.dto2entity(merchantDTO);

        //调用mapper更新商户表
        merchantMapper.updateById(entity);

    }


    /**
     * 根据手机号判断员工是否已在指定商户存在
     *
     * @param mobile 手机号
     * @return
     */
    private boolean isExistStaffByMobile(String mobile, Long merchantId) {
        int count = staffMapper.selectCount(new LambdaQueryWrapper<Staff>()
                .eq(Staff::getMobile, mobile)
                .eq(Staff::getMerchantId, merchantId));
        return count > 0;
    }

    /**
     * 根据账号判断员工是否已在指定商户存在
     *
     * @param userName
     * @param merchantId
     * @return
     */
    private boolean isExistStaffByUserName(String userName, Long merchantId) {
        int count = staffMapper.selectCount(new LambdaQueryWrapper<Staff>()
                .eq(Staff::getUsername, userName)
                .eq(Staff::getMerchantId, merchantId));
        return count > 0;
    }

    /**
     * 查找根门店
     *
     * @param merchantId
     * @return 根门店id
     * @throws BusinessException
     */
    private Long getRootStore(Long merchantId) throws BusinessException {
        Store store = storeMapper.selectOne(new LambdaQueryWrapper<Store>().eq(Store::getMerchantId, merchantId).isNull(Store::getParentId));
        if (store == null) {
            throw new BusinessException(CommonErrorCode.E_200014);
        }
        return store.getId();
    }

}

